package com.ymttest.database.mongo;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.ymt.core.tool.Logger;
import com.ymt.database.MongoDBDriver;
import com.ymttest.business.service.AssertService;
import com.ymttest.utils.EnvSetup;
import com.ymttest.utils.MapUtil;
import com.ymttest.utils.YMTDateUtil;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class YmtMongoDriverFactroy implements MethodInterceptor{
	public static boolean isCheckMgoProdData = false;
	
	public static boolean IsNewJavaMongoOpen = true;
	public static boolean IsNewMongoOpen = false;
	public static boolean IsOldMongoOpen = false;
	public static boolean IsEsCheck = true;
	
	
	public static double waitSec = 1;
	public static int retryTime = 2;
	
	public static boolean isNewMongoCheck(){return isMongoChk(IsNewMongoOpen);}
	
	public static boolean isOldMongoCheck(){return isMongoChk(IsOldMongoOpen);}
	
	public static boolean isNewJavaMgoCheck(){return isMongoChk(IsNewJavaMongoOpen);}

	public static boolean isEsCheck(){return isMongoChk(IsEsCheck);}
	
	private static boolean isMongoChk(boolean paramSet){
		if (paramSet){
			YMTDateUtil.waitTime(0.5);
			return true;
		}else{
			return false;
		}
	}
	
	private static MongoDBDriver YmtProductDBdriverNewJava = null;
	private static MongoDBDriver YmtShoppingCartDBdriverNewJava = null;
	private static MongoDBDriver YmtProductDBdriver = null;
	private static MongoDBDriver YmtProductDBdriverNew = null;
	
	private static MongoDBDriver SellerPromotionDBdrive = null;
	private static MongoDBDriver YmtShoppingCartDBdriverNew = null;
	private static MongoDBDriver ProductHis = null;
	
	
	/***
	 * 新java版  mongo服务连接
	 */
	public static MongoDBDriver getInstance_YmtProductDBdriverNewJava(String collectionname){
		return getInstance(YmtProductDBdriverNewJava,"YmtProducts",collectionname,EnvSetup.getSystemUrl("set5_mongoip"),27017,"ymtproducts_user","123456");
	}
	
	
	public static MongoDBDriver getInstance_YmtShoppingCartDBdriverNewJava(String collectionname){
		return getInstance(YmtShoppingCartDBdriverNewJava,"Ymt_ShoppingCart",collectionname,EnvSetup.getSystemUrl("set5_mongoip"),27017,"shoppingcartuser","123456");
	}
	
	
	/***
	 * 老Mongo 服务连接
	 * @param collectionname
	 * @return
	 */
	public static MongoDBDriver getInstance_YmtProductDBdriver(String collectionname){
		//for Mongo2.6
//		return getInstance(YmtProductDBdriver,"YmtProductDB",collectionname,EnvSetup.getSystemUrl("set1_mongoip"));
		
		//for Mongo3.0
		return getInstance(YmtProductDBdriver,"YmtProductDB",collectionname,EnvSetup.getSystemUrl("set5_mongoip"));
	}
	
	
	/***
	 * 新Mongo 服务连接
	 * @param collectionname
	 * @return
	 */
	public static MongoDBDriver getInstance_YmtProductDBdriverNew(String collectionname){
		return getInstance(YmtProductDBdriverNew,"YmtBuyerProduct",collectionname,EnvSetup.getSystemUrl("set5_mongoip"),27017,"BuyerProductuser","123456");
	}
	
	/***
	 * ProductSnapshot 服务连接
	 * @param collectionname
	 * @return
	 */
	public static MongoDBDriver getInstance_ProductSnapshotDBdriverNew(String collectionname){
		return getInstance(YmtProductDBdriverNew,"ProductSnapshot",collectionname,EnvSetup.getSystemUrl("set5_mongoip"),27017,"BuyerProductuser","123456");
	}
	
	/***
	 * 新Mongo 历史库连接
	 * @param collectionname
	 * @return
	 */
	public static MongoDBDriver getInstance_ProductHis(String collectionname){
		return getInstance(ProductHis,"ProductHis",collectionname,EnvSetup.getSystemUrl("set5_mongoip"),27017,"producthisuser","123456");
	}
	
	/***
	 * java Mongo 服务连接
	 * @param collectionname
	 * @return
	 */
	public static MongoDBDriver getInstance_YmtProductsDBdriver(String collectionname){
		return getInstance(YmtProductDBdriverNew,"YmtProducts",collectionname,EnvSetup.getSystemUrl("set5_mongoip"),27017,"ymtproducts_user","123456");
	}
	/*
	 * 连接满减促销数据库mongo
	 */
	public static MongoDBDriver getInstance_SellerPromotionDBdriverNew(String collectionname){
		return getInstance(SellerPromotionDBdrive,"sellerpromotion",collectionname,EnvSetup.getSystemUrl("set5_mongoip"),27017,"sellerpromotionuser","123456");
	}
	
	private static MongoDBDriver getInstance(MongoDBDriver driver,String dbName,String collectionname,String host){
		return getInstance(driver,dbName,collectionname,host,27017,"productuser","123456");
	}
	
	public static MongoDBDriver getInstance_YmtShoppingCartDBdriverNew(String collectionname){
		return getInstance(YmtShoppingCartDBdriverNew, "Ymt_ShoppingCart", collectionname, EnvSetup.getSystemUrl("set5_mongoip"),27017, "shoppingcartuser", "123456");
	}
	
	/***
	 * 获取代理对象
	 */
	private static MongoDBDriver getInstance(MongoDBDriver driver,String dbName,String collectionname, String host,int port,String userName,String pswd){
		try {
		
			 Enhancer enhancer = new Enhancer();
			 enhancer.setSuperclass(MongoDBDriver.class);
			 enhancer.setCallback(new YmtMongoDriverFactroy());
			 
			 driver = (MongoDBDriver)enhancer.create(new Class[]{String.class,int.class,String.class},
					 new Object[]{host,port ,dbName});
			 driver.auth(userName, pswd);
			
			driver.selectCollection(collectionname);
			return driver;
		}catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
 

	/***
	 * 代理 尝试重试搜取mongo
	 */
	@Override
	public  Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		Object result = null;
		//用代理
		if (method.getName().equals("selectPartLimitToMap")){
			StackTraceElement sElement= Thread.currentThread().getStackTrace()[3];
//			Logger.debug("代理查询 class:["+sElement.getFileName()+"],method:["+sElement.getMethodName()+"]");
			
			for(int i=0;i<retryTime;i++){
//				Logger.comment("代理查询第"+(i+1)+"次");
				result = methodProxy.invokeSuper(obj, args);
				
				ArrayList<Map> listRet = (ArrayList<Map>)result;
				if (listRet.size()!=0){return result;}
				
				if(i<retryTime-1){YMTDateUtil.waitTime((1)*waitSec);Logger.comment("wait "+(1)*waitSec +" s");}
			}
			
			ArrayList<Map> listRet = (ArrayList<Map>)result;
			if (listRet.size()==0){
				Logger.comment("mongo result is empty. funtion name["+method.getName() +"]");
			}
		}else{
			result = methodProxy.invokeSuper(obj, args);
		}
		return result;
		
	}

	
	/***
	 * isUpdate("LiveModel",MapUtil.hashMap("ActivityId", 148186),MapUtil.hashMap("Action", 1))
	 * 等待Mongo修改成功尝试机制
	 * @param collectionname 
	 * @param selectMap
	 * @param isUpdateMap
	 * @return
	 * @throws Exception
	 */
	public static boolean isUpdate(String collectionname,Map<String,Object> selectMap,Map<String, Object> isUpdateMap) throws Exception{
		MongoDBDriver mdd = YmtMongoDriverFactroy.getInstance_YmtProductsDBdriver(collectionname);
		Map<String, Object> ret = new HashMap<String,Object>();
		
		boolean isAllMatch = true;
		
		for(int i=0;i<retryTime;i++){
			ret = mdd.selectPartLimitToMap(selectMap,1).get(0);
			isAllMatch = true;
				
			for(String k:isUpdateMap.keySet()){
				boolean checkRet = AssertService.assertPreCheck(isUpdateMap.get(k), ret.get(k));
				if (!checkRet){
					isAllMatch = false;
					YMTDateUtil.waitTime(waitSec);
					break;
				}
			}
			if (isAllMatch){return true;}
		}
		return isAllMatch;
	}
	
	public static void main(String[] args) throws Exception {
		isUpdate("LiveModel",MapUtil.hashMap("ActivityId", 148186),MapUtil.hashMap("Action", 1));
	}
}


